package com.syl.springcloud.authorization.controller;

import com.syl.springcloud.authorization.bean.AccessToken;
import com.syl.springcloud.authorization.bean.AuthorizationConfig;
import com.syl.springcloud.authorization.bean.ReturnMessage;
import com.syl.springcloud.authorization.util.HttpUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.syl.springcloud.authorization.constant.BaseConstant.TOKEN_CACHE;

/**
 *
 * @author syl
 * @create 2018-08-10 9:45
 **/
@RestController
@RequestMapping("token")
public class TokenController {

    @Autowired
    private AuthorizationConfig authorizationConfig;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    private static List<String> CLIENTS = new ArrayList<>();
    static {
        CLIENTS.add("iadmin");
    }

    @RequestMapping("/get/access_token/{clientId}")
    public String getAccessToken(@PathVariable("clientId") String clientId, @RequestParam(required = false) String code, HttpServletRequest request, HttpServletResponse response){
        if(StringUtils.isBlank(clientId))return new ReturnMessage(400, "clientId不能为空").toJson();
        if(!CLIENTS.contains(clientId))return new ReturnMessage(400, "非法的clientId").toJson();
        String redisKey = request.getSession().getId() + "_" + clientId + "_" + TOKEN_CACHE;
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        if(redisTemplate.hasKey(redisKey)){
            return opsForValue.get(redisKey);
        }
        String appPath = "http://"+ request.getServerName()+ ":"+ request.getServerPort() + request.getContextPath();
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("client_id",clientId);
        paramMap.put("redirect_uri", appPath + "/token/get/access_token/"+clientId);
        HttpUtils httpUtils = new HttpUtils(restTemplate);
        if(StringUtils.isEmpty(code)) {
            paramMap.put("response_type","code");
            HttpHeaders headers = getHeader(request);
//            headers.set(HttpHeaders.COOKIE, "JSESSIONID="+request.getSession().getId());
            //开始递归
            String json = httpUtils.getForString(appPath + "/oauth/authorize", paramMap, headers);
            return json;
        }else {
            paramMap.put("code", code);
            paramMap.put("grant_type", "authorization_code");
            paramMap.put("client_secret", authorizationConfig.getSecret());
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            // again
            AccessToken token = httpUtils.postForObject(appPath + "/oauth/token", paramMap, AccessToken.class, headers);
            String json = new ReturnMessage(200, token.getAccess_token()).toJson();
            opsForValue.set(redisKey,json,token.getExpires_in(),TimeUnit.SECONDS);
            return json;
        }
    }

    private HttpHeaders getHeader(HttpServletRequest request){
        HttpHeaders headers = new HttpHeaders();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key =  headerNames.nextElement();
            String value = request.getHeader(key);
            headers.set(key, value);
        }
        return headers;
    }

}
